package com.shi.shiro.controller;

import cn.hutool.core.bean.BeanUtil;
import com.shi.shiro.common.Result;
import com.shi.shiro.domain.Permission;
import com.shi.shiro.domain.Role;
import com.shi.shiro.domain.User;
import com.shi.shiro.dto.UserLoginDTO;
import com.shi.shiro.dto.UserRegisterDTO;
import com.shi.shiro.service.UserService;
import com.shi.shiro.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/users")
@Slf4j
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 查询用户列表
     * @return
     */
    @RequiresAuthentication
    @RequiresRoles(value = {"user","admin"},logical = Logical.OR)
//    @RequiresPermissions(value = {"users:get"})
    @GetMapping
    public Object getUserList() {
        log.info("查询用户列表");
        return "用户列表";
    }

    /**
     * 用户登录
     * @param userLoginDTO
     * @param response
     * @return
     */
    @PostMapping("/login")
    public Result login(@RequestBody @Valid UserLoginDTO userLoginDTO, HttpServletResponse response) {
        log.info("进入用户登录请求...");
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(new UsernamePasswordToken(userLoginDTO.getUsername(), userLoginDTO.getPassword()));
        } catch (UnknownAccountException e) {
            throw new RuntimeException("用户名错误");
        } catch (IncorrectCredentialsException e) {
            throw new RuntimeException("密码错误");
        }
        User user = (User) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        // 登录成功后查询用户的详细信息，返回前端
        List<Role> roleList = userService.getRolesByUserId(user.getId());
        user.setRoleList(roleList);
        roleList.forEach(role -> {
            List<Permission> permissionList = userService.getPermissionsByRoleId(role.getId());
            role.setPermissionList(permissionList);
        });

        UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
        // 生成token
        String token = UUID.randomUUID().toString();
        // 设置响应头，将token返回
        response.setHeader("Authorization", token);
        redisTemplate.opsForValue().set(token,user,30, TimeUnit.MINUTES);
        return Result.ok(userVO);
    }

    @RequiresAuthentication
    @PostMapping("/logout")
    public Object logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "退出成功";
    }

    /**
     * 用户注册
     * @param userRegisterDTO
     * @return
     */
    @PostMapping("/register")
    public Result registerUser(@RequestBody @Valid UserRegisterDTO userRegisterDTO){
        boolean b = userService.registerUser(BeanUtil.copyProperties(userRegisterDTO, User.class));
        return Result.ok("注册成功");
    }
}

